package com.tbit.uqbike.service.business.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tbit.uqbike.annos.EncapsulateMap;
import com.tbit.uqbike.object.pojo.*;
import com.tbit.uqbike.object.pojo.dto.PackageDelayDTO;
import com.tbit.uqbike.object.value.UserRcDetail;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.service.business.VipCardService;
import com.tbit.uqbike.webmanager.dao.capital.RefundLogDao;
import com.tbit.uqbike.webmanager.dao.core.VipCardDao;
import com.tbit.uqbike.webmanager.dao.stat.VipCardOrderDayStaDao;
import com.tbit.utils.DateTimeUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Author: chen
 * @Description: 会员卡
 * @Date: 创建于 11:30 2020/7/6
 */
@Service
public class VipCardServiceImpl implements VipCardService {
    @Autowired
    private VipCardDao vipCardDao;
    @Autowired
    private VipCardOrderDayStaDao vipCardOrderDayStaDao;
    @Autowired
    private RefundLogDao refundLogDao;

    @Override
    public List<VipCard> queryPage(Integer accountId, Integer pageNO, Integer rowCount) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("accountId", accountId);
        params.put("rowCount", rowCount);
        params.put("page", (pageNO - 1) * rowCount);
        return vipCardDao.queryPage(params);
    }

    @Override
    public Integer queryCount(Integer accountId) {
        return vipCardDao.queryCount(accountId);
    }

    @Override
    public void add(VipCard vipCard) {
        vipCard.setCreateTime(new Date());
        vipCard.setUpdateTime(new Date());
        vipCardDao.add(vipCard);
    }

    @Override
    public void update(VipCard vipCard) {
        vipCard.setUpdateTime(new Date());
        vipCardDao.update(vipCard);
    }

    @Override
    public void del(VipCard vipCard) {
        vipCardDao.del(vipCard);
    }

    @Override
    public void edit(Integer vipId) {
        vipCardDao.edit(vipId);
    }

    @Override
    public List<UserMember> userVipPage(Integer accountId, Integer userId, String phone, Integer pageNO, Integer rowCount, Date startTime, Date endTime) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("userId", userId);
        params.put("phone", phone);
        params.put("accountId", accountId);
        params.put("rowCount", rowCount);
        params.put("page", (pageNO - 1) * rowCount);
        params.put("startTime", startTime);
        params.put("endTime", endTime);
        return vipCardDao.userVipPage(params);
    }

    @Override
    public Integer userVipCount(Integer accountId, Integer userId, String phone, Date startTime, Date endTime) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("userId", userId);
        params.put("phone", phone);
        params.put("accountId", accountId);
        params.put("startTime", startTime);
        params.put("endTime", endTime);
        return vipCardDao.userVipCount(params);
    }

    @Override
    public List<StatPark> groupByDay(Integer accountId, Long startTime, Long endTime) {
        List<StatPark> statParks = new ArrayList<>();
        Date now = new Date();
        long nowTime = now.getTime();
        String ymd = DateTimeUtil.formatDateYMD(now);
        String time = ymd + " 00:00:00";
        long morningStartTime = DateTimeUtil.StringToDateTime(time).getTime();
        time = ymd + " 03:00:00";
        long nightStartTime = DateTimeUtil.StringToDateTime(time).getTime();
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("accountIds", accountId);
        params.put("startTime", new Date(startTime));
        params.put("endTime", new Date(endTime));
        Map<String, StatPark> stat = new HashMap<>();
        List<String> daysStr = DateTimeUtil.findDaysStr(DateTimeUtil.formatDateYMD(new Date(startTime)), DateTimeUtil.formatDateYMD(new Date(endTime)));
        List<StatPark> statParks1 = vipCardOrderDayStaDao.groupByDay(params);
        for (StatPark statPark : statParks1) {
            stat.put(statPark.getName(), statPark);
        }
        daysStr.forEach(day -> {
            Date start = DateTimeUtil.getYesterdayHHMMSS(day, -1);
            Date end = DateTimeUtil.getYesterdayHHMMSS(day, 0);
            params.put("startTime", start);
            params.put("endTime", end);
            if (DateTimeUtil.formatDateYMD(end).equals(DateTimeUtil.getNowTimeYMD())) {
                statParks.add(vipCardDao.groupByDay(params).get(0));
            } else if (nowTime >= morningStartTime && nowTime < nightStartTime && day.equals(DateTimeUtil.getYesterday())) {
                /**兼容0-3点前一日订单未统计*/
                statParks.add(vipCardDao.groupByDay(params).get(0));
            } else {
                if (stat.containsKey(day)) {
                    statParks.add(stat.get(day));
                } else {
                    statParks.add(new StatPark(0, 0, day));
                }
            }
        });
        return statParks;
    }

    @Override
    public List<UserRcDetail> page(Integer accountId, Integer type, Long startTime, Long endTime,
                                   Integer pageNO, Integer rowCount) {
        Map<String, Object> params = new HashMap<>();
        params.put("accountId", accountId);
        if (startTime != null) {
            params.put("startTime", new Date(startTime));
        }
        if (endTime != null) {
            params.put("endTime", new Date(endTime));
        }
        params.put("type", type);
        params.put("page", (pageNO - 1) * rowCount);
        params.put("rowCount", rowCount);
        return vipCardDao.page(params);
    }

    @Override
    public Integer count(Integer accountId, Integer type, Long startTime, Long endTime) {
        Map<String, Object> params = new HashMap<>();
        params.put("accountId", accountId);
        if (startTime != null) {
            params.put("startTime", new Date(startTime));
        }
        if (endTime != null) {
            params.put("endTime", new Date(endTime));
        }
        params.put("type", type);
        return vipCardDao.count(params);
    }

    @Override
    public List<UserRcDetail> export(Integer accountId, Integer type, Long startTime, Long endTime) {
        Map<String, Object> params = new HashMap<>();
        params.put("accountId", accountId);
        if (startTime != null) {
            params.put("startTime", new Date(startTime));
        }
        if (endTime != null) {
            params.put("endTime", new Date(endTime));
        }
        params.put("vipType", type);
        return vipCardDao.export(params);
    }

    @Override
    @EncapsulateMap
    public List<Map<String, Object>> vipCountByType(HashMap<String, Object> params, Integer accountId, Integer type, Long startTime, Long endTime) {
        return vipCardDao.selectVipCountByType(params);
    }

    @Override
    @EncapsulateMap
    public MoneyData getTotalMoney(HashMap<String, Object> params, Integer accountId, Integer type, Long startTime, Long endTime) {
        return vipCardDao.getTotalMoney(params);
    }

    @Override
    public Result<String> modifyVipCardExpireTime(PackageDelayDTO delayDTO) {
        VipCardLog vipCard = vipCardDao.findVipCardLogByOrderNoAndUserId(delayDTO.getBusId(), delayDTO.getUserId());
        if (vipCard == null) {
            return Result.error("会员卡记录不存在");
        }
        List<RefundLog> refundLogs = refundLogDao.selectList(new LambdaQueryWrapper<RefundLog>().eq(RefundLog::getMerchantNO, vipCard.getOrderNO()));
        if (CollectionUtils.isNotEmpty(refundLogs)) {
            return Result.error("会员卡已产生退款,不能修改到期时间");
        }
        vipCard.setExpireDate(DateUtil.formatDate(new Date(delayDTO.getDelayTime())));
        vipCardDao.updateVipCardLog(vipCard);
        return Result.success();
    }

    @Override
    public UserMember userVipPageByAccountIdList(Integer userId, List<Integer> accountIdList) {
        return vipCardDao.userVipPageByAccountIdList(userId, accountIdList);
    }
}
